package com.cskaoyan.service.impl;

import com.cskaoyan.bean.data.GoodsDetailData;
import com.cskaoyan.bean.data.PageData;
import com.cskaoyan.bean.vo.GoodsSearchVo;
import com.cskaoyan.mapper.*;
import com.cskaoyan.model.*;
import com.cskaoyan.service.*;
import com.cskaoyan.util.MarketUtil;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author Pudding
 * @Date 2024/6/11 20:26
 */
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    MarketGoodsMapper goodsMapper;
    @Autowired
    MarketCategoryMapper categoryMapper;
    @Autowired
    CategoryService categoryService;
    @Autowired
    MarketGoodsAttributeMapper goodsAttributeMapper;
    @Autowired
    MarketGoodsProductMapper goodsProductMapper;
    @Autowired
    MarketGoodsSpecificationMapper goodsSpecificationMapper;
    @Autowired
    BrandService brandService;
    @Autowired
    CommentService commentService;
    @Autowired
    IssueService issueService;
    @Autowired
    CollectionService collectionService;


    @Override
    public List<MarketGoods> goodsList(boolean isHot, boolean isNew, int page, int limit) {
        //1. 构造查询条件
        MarketGoodsExample example = new MarketGoodsExample();
        //1.1 添加：没有删除的
        MarketGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        //1.2 拼接新品首发或人气推荐的产品
        if (isHot) {
            criteria.andIsHotEqualTo(true);
        }
        if (isNew) {
            criteria.andIsNewEqualTo(true);
        }
        //1.3 添加：按添加时间进行排序
        example.setOrderByClause("add_time desc");

        //2. 开启分页
        PageHelper.startPage(page, limit);

        //3. 进行查询
        List<MarketGoods> marketGoods = goodsMapper.selectByExample(example);
        return marketGoods;
    }

    @Override
    public List floorGoodsList(int categoryLimit, int categoryGoodsLimit) {
        //1. 创建首页商品类目表一级类目+商品类目表二级类目对应的商品封装的List
        List<Map> categoryList = new ArrayList<Map>();

        //2. 查询一级类目L1的List
        List<MarketCategory> catL1List = categoryService.list("L1", 1, categoryLimit);
        //3. 遍历一级类目List
        for (MarketCategory catL1 : catL1List) {
            Integer categoryId = catL1.getId();
            //3.1 根据一级类目的id查找对应多个二级类目中的任意受限个数的商品
            List<MarketGoods> categoryGoods = this.list(categoryId, 1, categoryLimit);

            //3.2 创建一个存放上述查询结果的Map（这个商品只存放三个字段id、name、goodsList）
            HashMap<String, Object> goodsMap = new HashMap<>();
            goodsMap.put("id", categoryId);
            goodsMap.put("name", catL1.getName());
            goodsMap.put("goodsList", categoryGoods);

            //3.3 将封装的map集合放到一级类目L1中
            categoryList.add(goodsMap);
        }

        return categoryList;
    }

    @Override
    public long count() {
        //1. 构造查询条件
        MarketGoodsExample example = new MarketGoodsExample();
        example.createCriteria().andDeletedEqualTo(false);
        //2. 进行条件查询所有商品数量
        long count = goodsMapper.countByExample(example);

        return count;
    }

    @Override
    public GoodsDetailData detail(Integer goodsId, int userId) {
        //1. 直接根据主键进行删除，如果你做的是逻辑删除，还要添加一个条件deleted=false
        MarketGoods marketGoods = goodsMapper.selectByPrimaryKey(goodsId);

        //2. 下面和market_goods表都是一对多的关系，查询条件都是goods_id = ? + deleted = false + order by
        List<MarketGoodsAttribute> attributes = this.getAttribute(goodsId);
        List<MarketGoodsProduct> products = this.getProducts(goodsId);
        List<Map> specificationList = this.getSpecifications(goodsId);

        //3.一个品牌对应多个商品，在商品表中有brand_Id
        Integer brandId = marketGoods.getBrandId();
        MarketBrand marketBrand = brandService.findByBrandId(brandId);

        //4. 用一个集合Map封装comment信息，一个是count、一个是comment表中信息(这里限制只显示前两条评论信息)
        //一个商品对应多个评论，在评论表中有value_id+type(评论类型如果type=0，则是商品评论；如果是type=1，则是专题评论)
        //先找出type=0的，再找value_id=goods_id,也就是该商品对应的多个评论，评论的类型（tinyint → Byte）
        Map<String, Object> commentMap = commentService.findByGoodsId(goodsId, (byte) 0, 1, 2);

        //5. 查询所有的常见问题
        List<MarketIssue> issues = issueService.findAll();

        //6. 用户是否有收藏
        //收藏类型，如果type=0，则是商品ID，且value_id=goods_id，且user_id为传入的值
        Integer userHasCollection = collectionService.hasCollection(goodsId, (byte) 0, userId);

        //封装商品详情数据到一个对象中
        GoodsDetailData data = GoodsDetailData.builder()
                .attribute(attributes)
                .productList(products)
                .specificationList(specificationList)
                .brand(marketBrand)
                .comment(commentMap)
                .info(marketGoods)
                .issue(issues)
                .userHasCollect(userHasCollection)
                .share(true)
                .shareImage("")
                .build();

        //返回商品详情数据
        return data;
    }

    @Override
    public List<MarketGoodsAttribute> getAttribute(Integer goodsId) {
        //1. 构造查询条件
        MarketGoodsAttributeExample example = new MarketGoodsAttributeExample();
        example.createCriteria().andDeletedEqualTo(false)
                .andGoodsIdEqualTo(goodsId);
        example.setOrderByClause("add_time desc");
        //2. 进行查询
        List<MarketGoodsAttribute> attributes = goodsAttributeMapper.selectByExample(example);
        return attributes;
    }

    @Override
    public List<MarketGoodsProduct> getProducts(Integer goodsId) {
        //1. 构造查询条件
        MarketGoodsProductExample example = new MarketGoodsProductExample();
        example.createCriteria().andDeletedEqualTo(false)
                .andGoodsIdEqualTo(goodsId);
        example.setOrderByClause("add_time desc");
        //2. 进行查询
        List<MarketGoodsProduct> products = goodsProductMapper.selectByExample(example);
        return products;
    }

    @Override
    public List<Map> getSpecifications(Integer goodsId) {
        //1. 构造查询条件
        MarketGoodsSpecificationExample example = new MarketGoodsSpecificationExample();
        example.createCriteria().andDeletedEqualTo(false)
                .andGoodsIdEqualTo(goodsId);
        example.setOrderByClause("add_time desc");
        //2. 进行查询
        List<MarketGoodsSpecification> specificationList = goodsSpecificationMapper.selectByExample(example);

        //3. 通过流将specificationList按照规范的名字分组，将转换为一个Map<name:String，MarketGoodsSpecification:List>存放所有的响应结果中的规范单个数据
        Map<String, List<MarketGoodsSpecification>> collect = specificationList.stream()
                .collect(Collectors.groupingBy(MarketGoodsSpecification::getSpecification));

        //4. 构建一个List<map>集合作为响应结果，存放specificationList中的所有元素，其中map的key = name:String、value = valueList:List
        List<Map> specificationMapList = new ArrayList<>();

        //5. 使用map集合的keySet()方法按照key，遍历上面的collect。collect.keySet()返回的是map接口中key组成的set集合
        for (String name : collect.keySet()) {
            //5.1 创建一个map，来存放specificationList中的name、valueList
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            map.put("valueList", collect.get(name));
            //5.2 将这个map封装到响应结果的List<Map>中
            specificationMapList.add(map);
        }

        return specificationMapList;
    }

    @Override
    //根据一级类目的id查找对应多个二级类目中的任意受限个数的商品
    public List<MarketGoods> list(Integer categoryId, int page, int limit) {
        //1. 创建一个存放商品的List
        List<MarketGoods> goodsList = new ArrayList<>();

        //2. 根据一级类目id查询对应的类目信息（一级类目信息中有level信息，可以做通用性配置）
        MarketCategory category = categoryService.findById(categoryId);
        //2.1 类目信息为空
        if (category == null) {
            return goodsList;
        }
        //2.2 类目等级为L1
        if ("L1".equals(category.getLevel())) {
            //查询所有的二级类目
            List<MarketCategory> marketCategories = categoryService.queryChildren(categoryId);
            //通过流只获取二级类目的id对应的List
            List<Integer> l2CategoryIds = marketCategories.stream()
                    .map(MarketCategory::getId)
                    .collect(Collectors.toList());
            //构建查询条件
            MarketGoodsExample example = new MarketGoodsExample();
            example.createCriteria().andDeletedEqualTo(false)
                    .andCategoryIdIn(l2CategoryIds);
            //开启分页限制
            PageHelper.startPage(page, limit);

            //进行查询
            goodsList = goodsMapper.selectByExample(example);
        }
        //2.3 类目等级为L2
        if ("L2".equals(category.getLevel())) {
            //构造查询条件，查询该二级类目下对应的商品（一对多关系，在多的一方也就是goods一方添加了一方的主键：category_id）
            MarketGoodsExample example = new MarketGoodsExample();
            example.createCriteria().andDeletedEqualTo(false)
                    .andCategoryIdEqualTo(categoryId);
            //开启分页限制
            PageHelper.startPage(page, limit);
            //进行条件查询
            goodsList = goodsMapper.selectByExample(example);
        }
        return goodsList;
    }

    @Override
    public List<MarketGoods> searchGoodsList(GoodsSearchVo goodsSearchVo) {
        //1. 构造查询条件
        MarketGoodsExample example = new MarketGoodsExample();
        example.createCriteria().andDeletedEqualTo(false)
                .andNameLike("%" + goodsSearchVo.getKeyword() + "%");
        example.setOrderByClause(goodsSearchVo.getSort() + " " + goodsSearchVo.getOrder());

        //2. 开启分页
        PageHelper.startPage(goodsSearchVo.getPage(), goodsSearchVo.getLimit());

        //3. 进行条件查询
        List<MarketGoods> marketGoods = goodsMapper.selectByExample(example);

        return marketGoods;
    }

    @Override
    public List<MarketGoods> listByBrandId(GoodsSearchVo goodsSearchVo) {
        //1. 构造查询条件
        MarketGoodsExample example = new MarketGoodsExample();
        example.createCriteria().andDeletedEqualTo(false)
                .andBrandIdEqualTo(goodsSearchVo.getBrandId());
        example.setOrderByClause("add_time" + " " + "desc");

        //2. 进行查询
        List<MarketGoods> marketGoods = goodsMapper.selectByExample(example);

        return marketGoods;
    }

    @Override
    public List<MarketGoods> list(GoodsSearchVo goodsSearchVo) {
        MarketGoodsExample example = new MarketGoodsExample();
        //1. 构造不同条件下的查询条件
        MarketGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        if (MarketUtil.isNotEmpty(goodsSearchVo.getBrandId())) {
            criteria.andBrandIdEqualTo(goodsSearchVo.getBrandId());
        }
        if (MarketUtil.isNotEmpty(goodsSearchVo.getIsHot())) {
            criteria.andIsHotEqualTo(goodsSearchVo.getIsHot());
        }
        if (MarketUtil.isNotEmpty(goodsSearchVo.getIsNew())) {
            criteria.andIsNewEqualTo(goodsSearchVo.getIsNew());
        }
        if (goodsSearchVo.getKeyword() != null && !goodsSearchVo.getKeyword().isEmpty()){
            criteria.andNameLike("%" + goodsSearchVo.getKeyword() + "%");
        }
        if (goodsSearchVo.getSort() == null){
            example.setOrderByClause("add_time" + " " + "desc");
        }else {
            example.setOrderByClause(goodsSearchVo.getSort() + " " + goodsSearchVo.getOrder());
        }

        //2. 开启分页
        PageHelper.startPage(goodsSearchVo.getPage(), goodsSearchVo.getLimit());
        //3. 进行查询
        List<MarketGoods> marketGoods = goodsMapper.selectByExample(example);

        return marketGoods;
    }

    @Override
    public MarketGoods findById(Integer goodsId) {
        //1. 构造查询条件
        MarketGoodsExample example = new MarketGoodsExample();
        example.createCriteria().andDeletedEqualTo(false)
                .andIdEqualTo(goodsId);
        //2. 进行查询
        List<MarketGoods> marketGoods = goodsMapper.selectByExample(example);

        return marketGoods != null && marketGoods.size() == 1 ? marketGoods.get(0) : null;
    }

    @Override
    public PageData findRelatedGoodsByCategoryId(Integer categoryId, int page, int limit) {
        //1. 构造查询条件
        MarketGoodsExample example = new MarketGoodsExample();
        example.createCriteria().andDeletedEqualTo(false)
                .andCategoryIdEqualTo(categoryId);
        example.setOrderByClause("add_time desc");

        //2. 开启分页：之后就可以使用pageInfo对象封装信息了
        PageHelper.startPage(page, limit);

        //3. 进行查询
        List<MarketGoods> marketGoods = goodsMapper.selectByExample(example);

        //4. 返回响应数据中的list，通过下面的静态方法PageData.list()，可以获取分页的pages、total信息
        return PageData.list(marketGoods);
    }
}
